/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package transervfx.Dato.DAO;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import transervfx.Dato.Entidad.Cliente;
import transervfx.Dato.Entidad.Fisico;
import transervfx.Dato.Entidad.Juridico;
import transervfx.Dato.Entidad.Localidad;
import transervfx.Dato.Entidad.Lugar;
import transervfx.Dato.Entidad.LugarPersonalFrecuente;

/**
 *
 * @author oscar
 */
public class ClienteDAO implements Dao<Cliente, Long> {

    private static ClienteDAO INSTANCE = null;

    /**
     * Crea el Gestor Auxiliar
     */
    protected ClienteDAO() {
    }

    /**
     * creador sincronizado para protegerse de posibles problemas multi-hilo
     * otra prueba para evitar instanciaciÃ³n mÃºltiple
     */
    private synchronized static void createInstance() {
        if (INSTANCE == null) {
            INSTANCE = new ClienteDAO();
        }
    }

    /**
     * Obtiene la instancia.
     *
     * @return devuelve la instancia del "GestorAuxiliar".
     */
    public static ClienteDAO getInstance() {
        if (INSTANCE == null) {
            createInstance();
        }
        return INSTANCE;
    }

    @Override
    public void persist(Cliente entity) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {
            EntityTransaction t = em.getTransaction();
            try {
                t.begin();
                em.persist(entity);
                t.commit();
            } finally {
                if (t.isActive()) {
                    t.rollback();
                }
            }
        } finally {
            em.close();
        }
    }

    //donde puedo meter una ventana de exito?
    //en el crear repartidor cuando acepta
    //ahi te lo busco
    @Override
    public void remove(Cliente entity) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            EntityTransaction t = em.getTransaction();
            try {
                t.begin();
                System.out.println("ESTAS POR ELIMIAR");
                entity = em.getReference(Cliente.class, entity.getId());
                em.remove(entity);
                System.out.println("LO ELIMINA");
                t.commit();
            } finally {
                if (t.isActive()) {
                    t.rollback();
                }
            }
        } finally {
            em.close();
        }
    }

    @Override
    public void update(Cliente entity) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {


            em.getTransaction().begin();
            System.out.println("Entra a modificar el cliente");
            em.merge(entity);

            em.getTransaction().commit();
            System.out.println("Lo modifica al cliente");

        } finally {
            em.close();
        }
    }

    @Override
    public Cliente findById(Long id) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            Query query = em.createNamedQuery("Cliente.findById");
            query.setParameter("id", id);
            if (query.getResultList().isEmpty()) {
                return null;
            }
            Cliente c = (Cliente) query.getResultList().get(0);
            c.getDomicilio();
            if (!c.getLugaresPersonalesFrecuentes().isEmpty()) {

                c.getLugaresPersonalesFrecuentes().get(0);
            }
            return (Cliente) query.getResultList().get(0);

        } finally {
            em.close();
        }
    }

    @Override
    public List<Cliente> findAll() {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            return em.createNamedQuery("Cliente.findAll").getResultList();

        } finally {
            em.close();
        }
    }

    public List<Fisico> findAllFisico() {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            return em.createNamedQuery("Fisico.findAll").getResultList();

        } finally {
            em.close();
        }
    }

    public List<Juridico> findAllJuridico() {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            return em.createNamedQuery("Juridico.findAll").getResultList();

        } finally {
            em.close();
        }
    }

    public Fisico findFisicoByTipoDocAndNroDoc(String tipoDoc, Integer nroDoc) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            Query query = em.createNamedQuery("Fisico.findByTipoDocAndNroDoc");
            query.setParameter("tipoDoc", tipoDoc);
            query.setParameter("nroDoc", nroDoc);

            List<Fisico> lr = query.getResultList();
            if (lr.size() > 0) {
                return lr.get(0);
            } else {
                return null;
            }


        } finally {
            em.close();
        }
    }

    public Juridico findJuridicoByCuit(Integer cuit) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {
            Query query = em.createNamedQuery("Juridico.findByCuit");
            query.setParameter("cuit", cuit);
            if (query.getResultList().isEmpty()) {
                return null;
            }
            return (Juridico) query.getResultList().get(0);
        } finally {
            em.close();
        }
    }

    public List<Fisico> findFisicoByNombresAndApellido(String nombres, String apellido) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            Query query = em.createNamedQuery("Fisico.findByNombresAndApellido");
            query.setParameter("nombres", nombres);
            query.setParameter("apellido", apellido);

            return query.getResultList();

        } finally {
            em.close();
        }
    }

    public Juridico findJuridicoByRazonSocial(String razonSocial) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {


            Query query = em.createNamedQuery("Juridico.findByRazonSocial");
            query.setParameter("razonSocial", razonSocial);

            List<Juridico> lr = query.getResultList();
            if (lr.size() > 0) {
                return lr.get(0);
            } else {
                return null;
            }

        } finally {
            em.close();
        }
    }

    public Cliente findByCompleto(Cliente clienteSeleccionado) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            //poner find no reference
            clienteSeleccionado = em.find(Cliente.class, clienteSeleccionado.getId());

            clienteSeleccionado.getDomicilio();

            if (!clienteSeleccionado.getLugaresPersonalesFrecuentes().isEmpty()) {

                clienteSeleccionado.getLugaresPersonalesFrecuentes().get(0);
            }
            return clienteSeleccionado;

        } finally {
            em.close();
        }
    }

    public Fisico findFisicoByCompleto(Fisico clienteFisicoSeleccionado) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            //poner find no reference
            clienteFisicoSeleccionado = em.find(Fisico.class, clienteFisicoSeleccionado.getId());

            clienteFisicoSeleccionado.getDomicilio();

            if (!clienteFisicoSeleccionado.getLugaresPersonalesFrecuentes().isEmpty()) {
                clienteFisicoSeleccionado.getLugaresPersonalesFrecuentes().get(0);
            }
            return clienteFisicoSeleccionado;

        } finally {
            em.close();
        }
    }

    public Juridico findJuridicoByCompleto(Juridico clienteJuridicoSeleccionado) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            //poner find no reference
            clienteJuridicoSeleccionado = em.find(Juridico.class, clienteJuridicoSeleccionado.getId());

            clienteJuridicoSeleccionado.getDomicilio();

            if (!clienteJuridicoSeleccionado.getLugaresPersonalesFrecuentes().isEmpty()) {
                clienteJuridicoSeleccionado.getLugaresPersonalesFrecuentes().get(0);
            }
            return clienteJuridicoSeleccionado;

        } finally {
            em.close();
        }
    }

 

  

    public Lugar findLugar(Long id) {
        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {

            Query query = em.createNamedQuery("Cliente.findLugar");
            query.setParameter("id", id);
            if (query.getResultList().isEmpty()) {
                return null;
            }

            return (Lugar) query.getResultList().get(0);

        } finally {
            em.close();
        }
    }

     
    public List<Cliente> buscarPorFiltroRango(String nombre,  String tipoDocumento, Integer numeroDocumento, Integer cuit, String condicionIva, int ini, int fin) {
        
         //eso no deberia dar nada
        
        String consulta = "SELECT c FROM Cliente c";
        boolean hayotroParametro = true;
       
        

        if (!nombre.equals("") || !condicionIva.equals("") || cuit!=null || !tipoDocumento.equals("") || numeroDocumento!=null) {
            
            
            consulta = "SELECT c FROM Cliente c WHERE EXISTS (SELECT f FROM Fisico f WHERE f.id= c.id ";
           
              if (!nombre.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " CONCAT(f.nombres,' ', f.apellido) LIKE " + "'%" + nombre + "%'";
                hayotroParametro = true;
            }
               
            
            if (!tipoDocumento.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " f.tipoDoc LIKE " + "'" + tipoDocumento + "%'";


            }
            if (numeroDocumento!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }
                consulta = consulta + " f.nroDoc="+numeroDocumento ;

            }
            if (!condicionIva.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " f.condicionFrenteIva LIKE " + "'" + condicionIva + "%'";


            }
            if (cuit!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }
                consulta = consulta + " f.cuit="+cuit ;

            }
               consulta=consulta+")";

        }
        
      
        
         if ((tipoDocumento.isEmpty() & numeroDocumento==null) &(!nombre.equals("") || !condicionIva.equals("") || cuit!=null)) {
         
            consulta = consulta + "OR"
                    +" EXISTS (SELECT j FROM Juridico j WHERE j.id= c.id ";
            
           if (!nombre.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.razonSocial LIKE " + "'%" + nombre + "%'";
                hayotroParametro = true;
            }
          
            if (!condicionIva.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.condicionFrenteIva LIKE " + "'" + condicionIva + "%'";


            }
            if (cuit!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.cuit= "+ cuit;

            }
            
            consulta=consulta+")";

        }
        
        
        
        
        
        System.out.println(consulta);

        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {
            Query query = em.createQuery(consulta);
            query.setFirstResult(ini);
            query.setMaxResults(fin);

            return (List<Cliente>) query.getResultList();

        } finally {
            em.close();
        }
    }
    
    
    public Long cantidadClientePorFiltroRango(String nombre,  String tipoDocumento, Integer numeroDocumento,Integer cuit, String condicionIva) {
        
         
        
        String consulta = "SELECT COUNT(c) FROM Cliente c";
        boolean hayotroParametro = true;
       
        

        if (!nombre.equals("") || !condicionIva.equals("") || cuit!=null || !tipoDocumento.equals("") || numeroDocumento!=null) {
             
            consulta = "SELECT COUNT(c) FROM Cliente c WHERE EXISTS (SELECT f FROM Fisico f WHERE f.id= c.id ";
           
              if (!nombre.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " CONCAT(f.nombres,' ', f.apellido) LIKE " + "'%" + nombre + "%'";
                hayotroParametro = true;
            }
               
              if (!tipoDocumento.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " f.tipoDoc LIKE " + "'" + tipoDocumento + "%'";


            }
            if (numeroDocumento!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }
                consulta = consulta + " f.nroDoc="+numeroDocumento ;

            }
            if (!condicionIva.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " f.condicionFrenteIva LIKE " + "'" + condicionIva + "%'";


            }
            if (cuit!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }
                consulta = consulta + " f.cuit="+cuit ;

            }
               consulta=consulta+")";

        }
 
        
         if ((tipoDocumento.isEmpty() & numeroDocumento==null) &(!nombre.equals("") || !condicionIva.equals("") || cuit!=null)) {
         
            consulta = consulta + "OR"
                    +" EXISTS (SELECT j FROM Juridico j WHERE j.id= c.id ";
            
           if (!nombre.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.razonSocial LIKE " + "'%" + nombre + "%'";
                hayotroParametro = true;
            }
          
            if (!condicionIva.equals("")) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.condicionFrenteIva LIKE " + "'" + condicionIva + "%'";


            }
            if (cuit!=null) {
                if (hayotroParametro) {
                    consulta = consulta + " AND ";
                } else {
                    hayotroParametro = true;
                }

                consulta = consulta + " j.cuit= "+ cuit;

            }
            
            consulta=consulta+")";

        }
        
        
        
        
        
        System.out.println(consulta);

        EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        try {
            Query query = em.createQuery(consulta);
            

            return  (Long) query.getSingleResult();

        } finally {
            em.close();
        }
    }

   
   
}
